/*
 * Copyright (c) 2016 Breezee.org. All Rights Reserved.
 */

package com.kelai.common;

import javafx.util.Callback;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import com.kelai.common.exception.BreezeeException;
import com.kelai.common.exception.EntityNotFoundException;
import com.kelai.utils.DynamicSpecifications;

import java.util.List;

/**
 * 服务层高度抽象接口
 * 提供：保存，删除，按ID查找，按Code查找，列表查询，分页查询，条目数，状态更新
 * Created by Silence on 2016/4/15.
 */
public interface IServiceLayer<T extends PersistObject> {

    /**
     * 持久化对象
     *
     * @return 持久域对象
     */
    IRepository<T> getRepository();

    default void setRepository(IRepository<T> repository){};

    default void setRepository(String repositoryBean){};


    /**
     * 保存领域对象
     *
     * @param r        需要保存的对象
     * @param callback 回调函数
     * @return 保存后的对象
     * @throws BreezeeException 保存一次
     */
    default T saveInfo(T r, Callback<T, Object>... callback) throws BreezeeException {
        return getRepository().saveEntity(r, callback);
    }


    /**
     * 删除指定主键的领域对象
     *
     * @param id 主键值
     * @throws BreezeeException
     */
    default void deleteById(String id) throws BreezeeException {
        if (id != null && id.trim().length() > 0)
            try {
                getRepository().delete(id);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BreezeeException(e.getMessage(), e);
            }
    }

    /**
     * 获取指定主键的领域对象
     *
     * @param id 主键值
     * @return 返回结果
     * @throws EntityNotFoundException 异常信息
     */
    default T findById(String id) throws EntityNotFoundException {
        try {
            return getRepository().findOne(id);
        } catch (Exception e) {
            e.printStackTrace();
            throw new EntityNotFoundException(e.getMessage(), e);
        }
    }

    /**
     * 获取指定业务主键的领域对象
     *
     * @param code 业务主键值
     * @return 返回查询结果
     * @throws EntityNotFoundException 异常信息
     */
    default T findByCode(String code) throws EntityNotFoundException {
        try {
            return getRepository().findByCode(code);
        } catch (Exception e) {
            e.printStackTrace();
            throw new EntityNotFoundException(e.getMessage(), e);
        }
    }

    /**
     * 根据条件获取领域对象列表
     * 查询条件作为BaseInfo的properties属性存在，以为了做校验
     *
     * @param t 带查询条件的对象
     * @return 返回列表对象
     * @throws BreezeeException 异常信息
     */
    default List<T> listAll(T t) throws BreezeeException {
        return getRepository().findAll(DynamicSpecifications.createSpecification(t.getProperties()), new Sort(Sort.Direction.DESC, "modifiedDate"));
    }

    /**
     * 分页获取指定条件的领域对象集合
     * 查询条件作为BaseInfo的properties属性存在，以为了做校验
     *
     * @param t 带查询条件的对象
     * @return 分页结果
     * @throws BreezeeException 异常信息
     */
    default InfoPage<T> pageAll(T t) throws BreezeeException {
        PageInfo pageInfo = new PageInfo(t.getProperties());
        if (t.getProperties().get("_sort") != null) {
            pageInfo.setSort((Sort) t.getProperties().get("_sort"));
        } else {
            pageInfo.setSort(new Sort(Sort.Direction.ASC, "rowNum","id"));
        }
        Page<T> page = getRepository().findAll(DynamicSpecifications.createSpecification(t.getProperties()),pageInfo);
        return new InfoPage<T>(page.getContent(),page.getTotalElements());
    }

    /**
     * 获取指定条件的集合数目
     *
     * @param t 查询条件
     * @return 条数
     * @throws BreezeeException 异常
     */
    default long count(T t) throws BreezeeException {
        return getRepository().count(DynamicSpecifications.createSpecification(t.getProperties()));
    }
}
